//
// Created by pzw on 24-3-22.
//

#ifndef QTTEST_FUNCADAPTER_H
#define QTTEST_FUNCADAPTER_H

#include <functional>
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>

class FuncAdapter {
public:/*bind and ref/cref*/
    template<typename Func, typename Ret, typename ...Args>
    static Ret std_func_bind(Func &&func, Args &&... args);
    template<typename Func, typename... Args>
    static typename std::result_of<Func(Args...)>::type std_func_bind2(Func &&func, Args &&... args);
    static void std_ref();
    static void std_ref2();

public:/* mem_fn */
    template<typename Func, typename Class, typename ...Args>
    static typename std::result_of<Func(Class *, Args...)>::type std_mem_fn(
            Class *classptr,
            Func func,
            Args...args
    );
    template<typename Tp, typename Class>
    inline static std::_Mem_fn<Tp Class::*> std_mem_fn2(Tp Class::* pm) noexcept;
    template<typename Tp, typename Class>
    inline static std::_Mem_fn<Tp Class::*> std_mem_fn3(Tp Class::* pm) noexcept;

public:/* function */
    static void std_func();
};


class Shape {
public:
    explicit Shape() = default;
    ~Shape() = default;
public:
    float radian = -1;

public:
    int draw() {
        return -1;
    }

    int draw2(float radn) {
        if (radn > 0) {
            /* do draw */
            return 0;
        }\
        /* draw errno */
        return -1;
    }
};


int std_round(double x) {
    return static_cast<double>(std::floor(x + 0.5));
}

std::function<int(double)> fn;

enum class Round_style {
    truncate, round
};

struct Round {
    Round_style style;

    explicit Round(Round_style ss) : style(ss) {}

    int operator()(double x) const {
        if (style == Round_style::round) {
            return x + 0.5;
        } else {
            return x;
        }
    }
};

int FuncAdapter_main();

#endif //QTTEST_FUNCADAPTER_H
